/**
 * 集合
 * 由一组无序且唯一的项组成的对象
 * 可以想象成一个既没有重复元素，也没有顺序概念的数组
 *
 * 集合操作
 * 并集：对于给定的两个集合，返回一个包含两个集合中所有元素的新集合
 * 交集：返回一个包含两个集合中共有的元素
 * 差集：返回一个包含所有存在于第一个集合且不存在于第二个集合的元素的新集合
 * 子集：验证一个给定集合是否是另一个集合的子集
 */

function MySet() { // ES6已经有了Set类，所以换个名字
	var items = {};  // 这里使用对象来表示集合

	this.add = function(value){
		if(!this.has(value)){
			items[value] = value;
			return true;
		}
		return false;
	}

	this.remove = function(value){
		if(this.has(value)){
			delete items[value];
			return true;
		}
		return false;
	}

	this.has = function(value){
		// return value in items;
		// 或者
		return items.hasOwnProperty(value);
	}

	this.keys = this.values = function(){
		return Object.keys(items);  // ES5

		var keys = [];
		for(var key in items){
			if(items.hasOwnProperty(key)){
				keys.push(key);
			}
		}
		return keys;
	}

	this.size = function(){
		return Object.keys(items).length; // ES5

		var count = 0;
		for(var prop in items){
			if(items.hasOwnProperty(prop)){
				count++;
			}
		}
		return count;
	}

	this.clear = function(){
		items = {};
	}

	// 并集 union
	this.union = function(otherSet){
		var unionSet = new MySet();

		var values = this.values();
		for(var i = 0; i < values.length; i++){
			unionSet.add(values[i]);
		}

		values = otherSet.values();
		for(var i = 0; i < values.length; i++){
			unionSet.add(values[i]);
		}

		return unionSet;
	}

	// 交集 intersection
	this.intersection = function(otherSet){
		var intersectionSet = new MySet();

		var values = this.values();

		for(var i = 0; i < values.length; i++){
			if(otherSet.has(values[i])){
				intersectionSet.add(values[i]);
			}
		}

		return intersectionSet;
	}

	// 差集 difference
	this.difference = function(otherSet){
		var differenceSet = new MySet();

		var values = this.values();
		for(var i = 0; i < values.length; i++){
			if(!otherSet.has(values[i])){
				differenceSet.add(values[i]);
			}
		}

		return differenceSet;
	}

	// 子集 subset
	this.isSubset = function(otherSet){
		if(this.size() > otherSet.size()){
			return false;
		}
		var values = this.values();

		for(var i = 0; i < values.length; i++){
			if(!otherSet.has(values[i])){
				return false;
			}
		}
		return true;
	}
}